package com.meego.common.io;

import com.meego.common.config.Config;
import com.meego.common.log.GA;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URL;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
import java.util.zip.ZipOutputStream;
import net.lingala.zip4j.core.ZipFile;
import net.lingala.zip4j.exception.ZipException;
import net.lingala.zip4j.model.ZipParameters;
import net.lingala.zip4j.util.Zip4jConstants;

public class Compress {

    public void createZipFile(OutputStream out, List<com.meego.common.util.ZipEntry> list, String onlineView) throws IOException {
        try {
            if (list == null || list.isEmpty()) {
                throw new IllegalArgumentException("List ZipEntry is <null> or Empty");
            }
            ZipOutputStream outStream = new ZipOutputStream(out);
            outStream.setComment("Autogenerated by " + Config.getStrConfig("", "HMTFramework") + ".\n\n"
                    + ((onlineView != null && !onlineView.isEmpty()) ? "You can view online at " + onlineView + "\n\n" : "")
                    + "Any questions, please contact minhtue0402@yahoo.com, phone: (+84)933 069 099\n\n"
                    + "DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING\n"
                    + "@generated");
            for (com.meego.common.util.ZipEntry entry : list) {
                outStream.putNextEntry(new ZipEntry(entry.getFileName()));
                switch (entry.getEntryType()) {
                    case com.meego.common.util.ZipEntry.FILE:
                        writeStreamToEntry(new FileInputStream(entry.getFile()), outStream);
                        break;
                    case com.meego.common.util.ZipEntry.INPUTSTREAM:
                        writeStreamToEntry(entry.getStream(), outStream);
                        break;
                    case com.meego.common.util.ZipEntry.STRING:
                        outStream.write(entry.getContent().getBytes());
                        break;
                    case com.meego.common.util.ZipEntry.URL:
                        writeStreamToEntry(entry.getUrl().openStream(), outStream);
                        break;

                    default:
                        GA.resource.warn("ZIPENTRY: Entry Type not support");
                        break;
                }
                outStream.closeEntry();
            }

            if (onlineView != null && !onlineView.isEmpty()) {
                outStream.putNextEntry(new ZipEntry(Config.getStrConfig("vs.file.zip.shortcut.url", "javavs.com")));
                outStream.write(("[InternetShortcut]\nURL=" + onlineView).getBytes());
            }
            outStream.close();

        } catch (IOException ex) {ex.printStackTrace();
            GA.resource.error("ZIPENTRY: Error occur when try to create Zip file", ex);
            throw ex;
        }
    }

    public void createZipFile(String filePath, List<com.meego.common.util.ZipEntry> list, String onlineView) throws IOException {
        FileOutputStream out = new FileOutputStream(filePath);
        createZipFile(out, list, onlineView);
    }

    private void writeStreamToEntry(InputStream in, ZipOutputStream out) throws IOException {
        try {
            byte[] buffer = new byte[1024];
            int bytesRead;

            // Each chunk of data read from the input stream is written to the output stream
            while ((bytesRead = in.read(buffer)) > 0) {
                out.write(buffer, 0, bytesRead);

            }
            in.close();
        } catch (IOException e) {
            throw e;
        }
    }

    public void extractZipFile(String zipfile, String extracteTo) {
        try {
            //Create input and output streams
            ZipInputStream inStream = new ZipInputStream(new FileInputStream(zipfile));

            ZipEntry entry;
            byte[] buffer = new byte[1024];
            int nrBytesRead;
            //Get next zip entry and start reading data
            File f = new File(extracteTo);
            if (!f.exists()) {
                f.mkdirs();
            }

            while ((entry = inStream.getNextEntry()) != null) {
                if (entry.isDirectory()) {
                    continue;
                }

                String filepath = f.getPath() + entry.getName().replace("\\", File.separator).replace("/", File.separator);
                File d1 = new File(Directory.getDirectoryPath(filepath));
                if(!d1.exists()){
                    d1.mkdirs();
                }
                OutputStream outStream = new FileOutputStream(filepath);
                while ((nrBytesRead = inStream.read(buffer)) > 0) {
                    outStream.write(buffer, 0, nrBytesRead);
                }
                outStream.close();
            }

            //Finish off by closing the streams			
            inStream.close();

        } catch (IOException ex) {
            ex.printStackTrace();
        }
    }

    public List<String> listContentsOfZipFile(String zipFile) throws IOException {
        List<String> list = new ArrayList<String>();
        try {
            java.util.zip.ZipFile zip = new java.util.zip.ZipFile(zipFile);

            Enumeration<? extends ZipEntry> zipEntries = zip.entries();

            while (zipEntries.hasMoreElements()) {
                ZipEntry entry = zipEntries.nextElement();
                if (entry.isDirectory()) {
                    continue;
                }
                list.add(entry.getName());
            }
            return list;
        } catch (IOException ex) {
            throw ex;
        }

    }

    public boolean addFilesWithStandardZipEncryption(ArrayList<File> source, String desFilePath, String password) {
        boolean zipResult = true;
        try {
            ZipFile zipFile = new ZipFile(desFilePath);

            ZipParameters parameters = new ZipParameters();
            parameters.setCompressionMethod(Zip4jConstants.COMP_DEFLATE); // set compression method to store compression

            // Set the compression level
            parameters.setCompressionLevel(Zip4jConstants.DEFLATE_LEVEL_NORMAL);

            // Set the encryption flag to true
            // If this is set to false, then the rest of encryption properties are ignored
            parameters.setEncryptFiles(true);

            // Set the encryption method to Standard Zip Encryption
            parameters.setEncryptionMethod(Zip4jConstants.ENC_METHOD_STANDARD);

            // Set password
            parameters.setPassword(password);

            zipFile.addFiles(source, parameters);

        } catch (ZipException e) {
            zipResult = false;
            e.printStackTrace();
        }
        return zipResult;
    }

    public static void main(String[] args) {
        try {

            FileOutputStream file = new FileOutputStream("D:\\test.zip");
            List<com.meego.common.util.ZipEntry> list = new ArrayList<com.meego.common.util.ZipEntry>();
            com.meego.common.util.ZipEntry textFile = new com.meego.common.util.ZipEntry("textFile.txt", "text file content");
            list.add(textFile);
//            com.meego.common.util.ZipEntry existFile = new com.meego.common.util.ZipEntry("test.jar", new File("D:\\test.jar"));
//            list.add(existFile);
            com.meego.common.util.ZipEntry url = new com.meego.common.util.ZipEntry("images/thucte-01.jpg", new URL("http://javavs.com/idangerous_files/1.jpg"));
            list.add(url);
            com.meego.common.util.ZipEntry ex = new com.meego.common.util.ZipEntry("ex.xls", new FileInputStream("D:\\ex.xls"));
            list.add(ex);
//            com.meego.common.util.ZipEntry qq = new com.meego.common.util.ZipEntry("js/ajax.js", new File("WebContent/js/ajax.js"));
//            list.add(qq);
            com.meego.common.util.ZipEntry shortcut = new com.meego.common.util.ZipEntry("javavs.com.url", "[InternetShortcut]\nURL=http://google.com.vn\nIconFile=Ice-Age-Ellie.ico\nIconIndex=0");
            list.add(shortcut);
            Compress compress = new Compress();
            compress.createZipFile(file, list, "http://google.com.vn/");

        } catch (FileNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
}
